package com.pai4j.pay.controller;

import com.pai4j.common.bean.APIResponseBean;
import com.pai4j.common.bean.APIResponseBeanUtil;
import com.pai4j.common.enums.payment.PaymentTransTypeEnum;
import com.pai4j.common.service.SnowflakeIdGeneratorService;
import com.pai4j.domain.dto.payment.PaymentOrderCreateDTO;
import com.pai4j.domain.dto.payment.PaymentOrderDTO;
import com.pai4j.domain.dto.payment.PaymentResultDTO;
import com.pai4j.domain.dto.payment.PaymentTransRequestDTO;
import com.pai4j.domain.dto.payment.PaymentTransferRequestDTO;
import com.pai4j.domain.enums.payment.PaymentResultCodeEnum;
import com.pai4j.pay.config.annotation.GetAppId;
import com.pai4j.pay.config.annotation.ValidateAccessPaymentPermission;
import com.pai4j.pay.service.PaymentApiService;
import com.pai4j.pay.service.PaymentOrderService;
import com.pai4j.rmi.pay.PaymentApiServiceClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;


@RestController
public class PaymentApiServiceController implements PaymentApiServiceClient {

    @Autowired
    private PaymentApiService paymentApiService;
    @Autowired
    private PaymentOrderService paymentOrderService;
    @Autowired
    private SnowflakeIdGeneratorService snowflakeIdGeneratorService;

    /**
     * 获取所有交易请求鉴权token
     *
     * @param appId
     * @param accessKey
     * @param secretKey
     * @param timestamp
     * @param signature
     * @param logId
     * @return
     */
    @Override
    public APIResponseBean<String> accessToken(@RequestHeader(name = "app-id") Long appId,
                                               @RequestHeader(name = "access-key") String accessKey,
                                               @RequestHeader(name = "secret-key") String secretKey,
                                               @RequestHeader Long timestamp,
                                               @RequestHeader String signature,
                                               @RequestHeader(name = "log-id") String logId) {

        String accessToken = paymentApiService.token(appId, accessKey, secretKey, timestamp, signature, logId);
        return APIResponseBeanUtil.success(accessToken);
    }

    /**
     * 获取分布式交易事务id
     *
     * 应用场景：如果上游接入方支付成功后业务异常，需要回滚交易数据
     *
     * @param accessToken
     * @param logId
     * @return
     */
    @ValidateAccessPaymentPermission
    @Override
    public APIResponseBean<String> transId(@RequestHeader(name = "access-token") String accessToken,
                                           @RequestHeader(name = "log-id") String logId) {

        String transId = paymentApiService.transId(accessToken);
        return APIResponseBeanUtil.success(transId);
    }

    @Override
    public APIResponseBean<String> orderId(@RequestHeader(name = "access-token") String token,
                                           @RequestHeader(name = "trans-id") String transId,
                                           @RequestHeader(name = "log-id") String logId,
                                           @RequestBody PaymentOrderCreateDTO paymentOrderCreateDTO) {
        // TODO 业务订单参数校验
        String orderId = paymentOrderService.createOrder(transId, logId, paymentOrderCreateDTO);
        return APIResponseBeanUtil.success(orderId);
    }

    /**
     * 真实交易（同时调用，一般用于内部支付场景，调用结束可以直接支付响应结果）
     *
     * @param paymentTransRequest
     * @param accessToken
     * @param logId
     *
     * @return 返回交易成功订单id
     */
    @ValidateAccessPaymentPermission
    @GetAppId
    @Override
    public APIResponseBean<Boolean> doTrans(@RequestBody PaymentTransRequestDTO paymentTransRequest,
                                            @RequestHeader(name = "access-token") String accessToken,
                                            @RequestHeader(name = "log-id") String logId) {

        PaymentResultDTO paymentResult = paymentOrderService.doTrans(paymentTransRequest);
        return APIResponseBeanUtil.success(PaymentResultCodeEnum.OK.getCode().equals(paymentResult.getCode()));
    }


    /**
     * 交易接口，（支持回调能力，一般应用场景是由用户来完成的，通过回调通知接入方/业务方）
     *
     * @param paymentTransRequest
     * @param accessToken
     * @param logId
     * @return
     */
    @GetAppId
    @Override
    public APIResponseBean<Boolean> trans(@RequestBody PaymentTransRequestDTO paymentTransRequest,
                                          @RequestHeader(name = "access-token") String accessToken,
                                          @RequestHeader(name = "log-id") String logId) {

        paymentOrderService.trans(paymentTransRequest);
        return APIResponseBeanUtil.success(true);
    }

    /**
     * 三方支付服务接口（由webchat-front-payment独立调用，需要登录限制）
     *
     * @param paymentTransferRequest
     * @param token
     * @param logId
     * @return
     */
    @ValidateAccessPaymentPermission
    @GetAppId
    @Override
    public APIResponseBean<PaymentResultDTO> transfer(@RequestBody PaymentTransferRequestDTO paymentTransferRequest,
                                             String token, String logId) {

        PaymentResultDTO paymentResultDTO = paymentOrderService.doTransfer(paymentTransferRequest);
        return APIResponseBeanUtil.success(paymentResultDTO);
    }

    @Override
    public APIResponseBean<PaymentOrderDTO> orderInfo(String orderId, String userId, String token) {

        PaymentOrderDTO order = paymentOrderService.getOrder(orderId, userId);
        return APIResponseBeanUtil.success(order);
    }

    /**
     * 交易回滚
     *
     * @param token
     * @param transId 回滚事务id
     * @param logId
     * @return
     */
    @ValidateAccessPaymentPermission
    @Override
    public APIResponseBean<Boolean> rollback(@RequestHeader(name = "access-token") String accessToken,
                                             @RequestHeader(name = "log-id") String logId,
                                             @RequestHeader(name = "trans-id")  String transId) {

        boolean rollbackResult = paymentOrderService.rollback(transId, logId);
        return APIResponseBeanUtil.success(rollbackResult);
    }

    /**
     * 查询账户余额
     *
     * @param account
     * @param logId
     * @return
     */
    @ValidateAccessPaymentPermission
    @Override
    public APIResponseBean<BigDecimal> balance(@PathVariable String account,
                                               @RequestHeader(name = "access-token") String accessToken,
                                               @RequestHeader(name = "log-id") String logId) {

        BigDecimal balance = paymentOrderService.getAccountBalanceFromCache(account);
        return APIResponseBeanUtil.success(new BigDecimal("100"));
    }
}
